﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Zhaoxi.Contorls
{
    /// <summary>
    /// Instrument.xaml 的交互逻辑
    /// </summary>
    public partial class Instrument : UserControl
    {
        // 依赖属性
        public Brush PlateBackGround {
            get { return (Brush)GetValue(PlateBackGroundProperty); }
            set { SetValue(PlateBackGroundProperty, value); }
        }
        public static readonly DependencyProperty PlateBackGroundProperty =
            DependencyProperty.Register("PlateBackGround", typeof(Brush), typeof(Instrument), 
                new PropertyMetadata(Brushes.Orange, new PropertyChangedCallback(OnPropertyChanged)));



        public Brush PlateTextColor {
            get { return (Brush)GetValue(PlateTextColorProperty); }
            set { SetValue(PlateTextColorProperty, value); }
        }
        public static readonly DependencyProperty PlateTextColorProperty =
            DependencyProperty.Register("PlateTextColor", typeof(Brush), typeof(Instrument),
                new PropertyMetadata(Brushes.White, new PropertyChangedCallback(OnPropertyChanged)));


        public Brush PointerColor {
            get { return (Brush)GetValue(PointerColorProperty); }
            set { SetValue(PointerColorProperty, value); }
        }
        public static readonly DependencyProperty PointerColorProperty =
            DependencyProperty.Register("PointerColor", typeof(Brush), typeof(Instrument), 
                new PropertyMetadata(Brushes.Green, new PropertyChangedCallback(OnPropertyChanged)));





        public double Maxmuin {
            get { return (double)GetValue(MaxmuinProperty); }
            set { SetValue(MaxmuinProperty, value); }
        }
        public static readonly DependencyProperty MaxmuinProperty =
            DependencyProperty.Register("Maxmuin", typeof(double), typeof(Instrument), 
                new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyChanged)));



        public double Minmuin {
            get { return (double)GetValue(MinmuinProperty); }
            set { SetValue(MinmuinProperty, value); }
        }
        public static readonly DependencyProperty MinmuinProperty =
            DependencyProperty.Register("Minmuin", typeof(double), typeof(Instrument),
                new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyChanged)));



        public double Value {
            get { return (double)this.GetValue(ValueProperty); }
            set { this.SetValue(ValueProperty, value); }
        }
        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(Instrument),
            new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyChanged)));

        public static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ( d as Instrument ).Refresh();
        }

        public Instrument()
        {
            InitializeComponent();

            this.SizeChanged += Instrument_SizeChanged;
        }

        private void Instrument_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            double minSize = Math.Min(this.RenderSize.Height, this.RenderSize.Width);
            this.elps.Width = minSize;
            this.elps.Height = minSize;
        }

        private void Refresh()
        {
            double Radius = this.elps.Width / 2.0;
            if (double.IsNaN(Radius)) return;

            double step = 270 / ( Maxmuin - Minmuin );
            double startAngle = -45.0;

            this.cvs.Children.Clear();
            for (int i = 0; i <= Maxmuin - Minmuin; i++) {
                Line scaleLine = new Line();

                double lineLength = ( i % 10 == 0 ) ? 10 : 5;

                scaleLine.X1 = Radius - ( ( Radius - 8 ) * Math.Cos(( i * step + startAngle ) * Math.PI / 180) );
                scaleLine.Y1 = Radius - ( ( Radius - 8 ) * Math.Sin(( i * step + startAngle ) * Math.PI / 180) );
                scaleLine.X2 = Radius - ( ( Radius - 8 - lineLength ) * Math.Cos(( i * step + startAngle ) * Math.PI / 180) );
                scaleLine.Y2 = Radius - ( ( Radius - 8 - lineLength ) * Math.Sin(( i * step + startAngle ) * Math.PI / 180) );

                scaleLine.Stroke = PlateTextColor;
                scaleLine.StrokeThickness = 1;

                this.cvs.Children.Add(scaleLine);

                if (i % 10 == 0) {
                    TextBlock textNum = new TextBlock();
                    textNum.Text = (i + Minmuin).ToString();
                    textNum.TextAlignment = TextAlignment.Center;
                    textNum.Width = 36;
                    textNum.FontSize = this.FontSize;

                    Canvas.SetLeft(textNum, Radius - ( ( Radius - 36 ) * Math.Cos(( i * step + startAngle ) * Math.PI / 180) ) - 17);
                    Canvas.SetTop(textNum, Radius - ( ( Radius - 36 ) * Math.Sin(( i * step + startAngle ) * Math.PI / 180) ) - 10);

                    textNum.Foreground = PlateTextColor;
                    this.cvs.Children.Add(textNum);
                }

            }

            DoubleAnimation da = new DoubleAnimation((this.Value - this.Minmuin) * step - 45, new Duration(TimeSpan.FromMilliseconds(200)));
            this.pointerAngel.BeginAnimation(RotateTransform.AngleProperty, da);

            string sData = "M {0} {1} A {0} {0} 0 1 1 {1} {2}";
            string pathData = string.Format(sData, Radius / 2, Radius, Radius * 1.5);
            var converter = TypeDescriptor.GetConverter(typeof(Geometry));
            this.circle.Data = (Geometry)converter.ConvertFromString(pathData);

            string pData = "M {0} {1},{1} {2},{1} {3}";
            string pathPData = string.Format(pData, Radius*0.3, Radius, Radius -5,Radius + 5);
            this.pointer.Data = (Geometry)converter.ConvertFromString(pathPData);


        }
    }
}
